package com.raymond.netty;

import com.alibaba.fastjson.JSONObject;
import com.raymond.enums.InterfaceEnum;
import com.raymond.redis.RedisConsumer;
import com.raymond.redis.RedisProducer;
import com.raymond.server.UserServer;
import com.raymond.utils.ErrorCode;
import com.raymond.utils.NettyHttpUtil;
import com.raymond.utils.Result;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;

/**
 * 获取请求
 *
 * @author :  raymond
 * @version :  1.0
 * @date :  2019/7/15
 */
@Component
@Slf4j
@ChannelHandler.Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {

    private final RedisProducer redisProducer;

    private final RedisConsumer redisConsumer;


    private final UserServer userServer;



    public ServerHandler(RedisProducer redisProducer, RedisConsumer redisConsumer, UserServer userServer) {
        this.redisProducer = redisProducer;
        this.redisConsumer = redisConsumer;
        this.userServer = userServer;
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        //判断是否是http请求
        if (!(msg instanceof FullHttpRequest)) {
            NettyHttpUtil.sendNotFound(ctx, null);
            ReferenceCountUtil.release(msg);
            return;
        }
        FullHttpRequest httpRequest = (FullHttpRequest) msg;
        String result = controlRequest(httpRequest);
        boolean keepAlive = HttpUtil.isKeepAlive(httpRequest);
        NettyHttpUtil.sendErrorCode(ctx,result,keepAlive);
        ReferenceCountUtil.release(msg);
    }

    /**
     * 控制请求到那个类那个方法
     * @param httpRequest httpRequest
     * @return 结果集
     */
    private String controlRequest(FullHttpRequest httpRequest) {
        String uri = httpRequest.uri();
        InterfaceEnum interfaceEnum = InterfaceEnum.getInterfaceEnum(uri);
        if (interfaceEnum == null) {
            log.warn("请求链接错误:{}", uri);
            return JSONObject.toJSONString(new Result(ErrorCode.URL_CODE));
        }
        JSONObject content = NettyHttpUtil.getJsonBody(httpRequest);
        String methodStr = NettyHttpUtil.getMethod(content);
        if (StringUtils.isEmpty(methodStr)) {
            log.warn("请求method错误:{}", methodStr);
            return JSONObject.toJSONString(new Result(ErrorCode.METHOD_CODE));
        }
        Method method;
        Object obj = new Object();
        try {
            if (interfaceEnum == InterfaceEnum.USER) {
                String data = NettyHttpUtil.getData(content);
                if (StringUtils.isEmpty(data)) {
                    method = userServer.getClass().getMethod(methodStr);
                    obj = method.invoke(userServer);
                } else {
                    method = userServer.getClass().getMethod(methodStr, String.class);
                    obj = method.invoke(userServer, data);
                }
            }
            Jedis jedis = new Jedis();
           return obj.toString();
        } catch (NoSuchMethodException e) {
            log.error("请求method错误:{}", methodStr, e);
            return JSONObject.toJSONString(new Result(ErrorCode.METHOD_CODE));
        } catch (IllegalAccessException e) {
            log.error("初始化{}类异常,method:{}", userServer.getClass().getName(), methodStr, e);
            return JSONObject.toJSONString(new Result(ErrorCode.METHOD_CODE));
        } catch (InvocationTargetException e) {
            log.error("{}类中{}方法异常", userServer.getClass().getName(), methodStr, e);
            return JSONObject.toJSONString(new Result(ErrorCode.METHOD_CODE));
        }
    }

}
